#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
 
 
#include <modbus/modbus.h>
#include <modbus/modbus-tcp.h>
 
#define LOOP          1
#define SERVER_ID     17
#define ADDRESS_START 0
#define ADDRESS_END   9
 
 
int main(void)
{
    modbus_t *ctx;
    int rc;
    int nb_fail;
    int nb_loop;
    int addr;
    int nb;
    uint8_t *tab_bits;
    uint8_t *tab_in_bits;
    uint16_t *tab_registers;
    uint16_t *tab_in_registers;
 
 
    ctx = modbus_new_tcp("192.168.0.233", 502);
    modbus_set_slave(ctx, SERVER_ID);
    modbus_set_debug(ctx, TRUE);
 
 
    if (modbus_connect(ctx) == -1) 
    {
        fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno));
        modbus_free(ctx);
        return -1;
    }
 
 
    /* Allocate and initialize the different memory spaces */
    nb = ADDRESS_END - ADDRESS_START;
 
 
    tab_bits = (uint8_t *) malloc(nb * sizeof(uint8_t));
    memset(tab_bits, 0, nb * sizeof(uint8_t));
 
 
    tab_in_bits = (uint8_t *) malloc(nb * sizeof(uint8_t));
    memset(tab_in_bits, 0, nb * sizeof(uint8_t));
 
 
    tab_registers = (uint16_t *) malloc(nb * sizeof(uint16_t));
    memset(tab_registers, 0, nb * sizeof(uint16_t));
 
 
    tab_in_registers = (uint16_t *) malloc(nb * sizeof(uint16_t));
    memset(tab_in_registers, 0, nb * sizeof(uint16_t));
 
 
 
 
    nb_loop = nb_fail = 0;
    while (nb_loop++ < LOOP) 
    {
        for (addr = ADDRESS_START; addr < ADDRESS_END; addr++) 
        {
            int i;
 
 
            nb = ADDRESS_END - addr;
 
 
            /* read BIT */
            
            rc = modbus_read_bits(ctx, addr, 1, tab_bits);
            if (rc != 1 ) 
            {
                printf("ERROR modbus_read_bits single (%d)\n", rc);
                printf("address = %d\n", addr);
                nb_fail++;
            }
            else
            {
                printf("Address = %d, value %d (0x%X) \n",
                                   addr,
                                   tab_bits[0],
                                   tab_bits[0]);
            }
            
 
 
            /* MULTIPLE BITS */
            
            rc = modbus_read_bits(ctx, addr, nb, tab_bits);
            if (rc != nb) 
            {
                printf("ERROR modbus_read_bits\n");
                printf("Address = %d, nb = %d\n", addr, nb);
                nb_fail++;
            } 
            else 
            {
                for (i = 0; i < nb; i++) 
                {
                    
                        printf("Address = %d, value %d (0x%X) \n",
                                addr+i,
                                tab_bits[i],
                                tab_bits[i]);
 
 
                }
            }
 
 
            //read input bits
            //modbus_read_input_bits
            
 
 
            /* SINGLE REGISTER */
            rc = modbus_read_registers(ctx, addr, 1, tab_registers);
            if (rc != 1) 
            {
                printf("ERROR modbus_read_registers single (%d)\n", rc);
                printf("Address = %d\n", addr);
                nb_fail++;
            } 
            else 
            {
                    printf("Address = %d, value = %d (0x%X) \n",
                            addr,
                            tab_registers[0],
                            tab_registers[0]);
            }
            
 
 
            /* MULTIPLE REGISTERS */
            
            rc = modbus_read_registers(ctx, addr, nb, tab_registers);
            if (rc != nb) 
            {
                printf("ERROR modbus_read_registers (%d)\n", rc);
                printf("Address = %d, nb = %d\n", addr, nb);
                nb_fail++;
            } 
            else 
            {
                for ( i = 0; i < nb; i++) 
                {
                        printf("Address = %d, value %d (0x%X) \n",
                                addr+i,
                                tab_registers[i],
                                tab_registers[i]);
 
 
                }
            }
            // read intput registers
            //modbus_read_input_registers
 
 
            sleep(5);
        }
 
 
        printf("Test: ");
        if (nb_fail)
            printf("%d FAILS\n", nb_fail);
        else
            printf("SUCCESS\n");
    }
 
 
    /* Free the memory */
    free(tab_bits);
    free(tab_in_bits);
    free(tab_registers);
    free(tab_in_registers);
 
 
    /* Close the connection */
    modbus_close(ctx);
    modbus_free(ctx);
 
 
    return 0;
}